#include "LandPlayerEvent.h"
#include "EconomyLand.h"
#include "Expand/Plugins/AuthPlugin.h"

#include "Log.h"
#include "GameRegistry.hpp"
#include "Player/PlayerData.h"
#include "Components/ComponentBody.h"
#include "Components/ComponentPlayer.h"
#include "Components/ComponentAttacker.h"
#include "Components/ComponentMiner.h"
#include "Components/ComponentOnFire.h"
#include "Components/ComponentBlockEntity.h"

#include "Network/PackageManager.h"
#include "Network/Packages/MessagePackage.h"
#include "Components/ComponentHealth.h"
#include "Subsystems/SubsystemTerrain.h"
#include "Blocks/CairnBlock.h"
#include "Blocks/DiamondBlock.h"
#include "Blocks/MatchBlock.h"
#include "Game/BodyRaycastResult.hpp"

namespace Economy
{

    static void sendMessage(ClientPtr client, const std::string & message)
    {
        std::shared_ptr<MessagePackage> package = std::make_shared<MessagePackage>(message);
        package->client = client;
        package->sendType = PackageSendType::TARGET;
        GameSingleton::packageManager->addSendPackageToQueue(package);
    }


    bool LandPlayerEvent::playerEditBlockEvent(std::shared_ptr<PlayerData> playerData, const Point3& point)
    {
        int32_t regionX = (point.posX >> 8);
        int32_t regionY = (point.posZ >> 8);

        GameGuid &playerGuid = playerData->playerGuid;
        uint32_t authLevel = m_economyLand->m_authPlugin->getLevelByGuid(playerGuid);
        // 管理员就不需要判断了，直接通过
        if (authLevel >= 100)
        {
            return true;
        }
        LandData *landDataPtr;
        if (m_economyLand->getLandData(regionX, regionY, landDataPtr) == true)
        {
            std::lock_guard<std::mutex> lk(landDataPtr->landDataMutex);

            // 五限制的区域直接通过
            if (landDataPtr->mode == LandType::None)
            {
                return true;
            }
            // 区域有权限的话，直接通过
            if (landDataPtr->authUserSet.find(playerGuid) != landDataPtr->authUserSet.end())
            {
                return true;
            }
            if (landDataPtr->mode == LandType::NeedBuyLand)
            {
                Point3 targetPoint((point.posX & 0xFF), (point.posY & 0xFF), (point.posZ & 0xFF));
                auto &userLand = landDataPtr->userLandVec;
                for(auto it = userLand.begin(); it != userLand.end(); ++it)
                {
                    if( it->chunkPointStart.posX <= targetPoint.posX && 
                        it->chunkPointStart.posY <= targetPoint.posY && 
                        it->chunkPointStart.posZ <= targetPoint.posZ &&
                        it->chunkPointEnd.posX >= targetPoint.posX && 
                        it->chunkPointEnd.posY >= targetPoint.posY &&
                        it->chunkPointEnd.posZ >= targetPoint.posZ)
                    {
                        if (it->userGuid == playerGuid)
                        {
                            return true;
                        }
                        else if (it->inviteUserSet.find(playerGuid) != it->inviteUserSet.end())
                        {
                            return true;
                        }
                        sendMessage(playerData->client, "这不是你的领地，无法编辑方块");
                        return false;
                    }
                }
                sendMessage(playerData->client, "你需要购买领地后才能编辑方块");
                return false;
            }
        }
        sendMessage(playerData->client, "你没有权限编辑方块");
        return false;
    }
    
    // 放置方块
    bool LandPlayerEvent::playerPlaceBlock(ComponentPlayer *componentPlayer, const Point3 &point, int32_t placeBlockValue)
    {
        return playerEditBlockEvent(componentPlayer->playerData, point);
    }
    // 破坏方块
    bool LandPlayerEvent::playerBreakBlock(ComponentPlayer *componentPlayer, const Point3 &point, int32_t digBlockValue, int32_t toolLevel)
    {
        return playerEditBlockEvent(componentPlayer->playerData, point);
    }
    // 打开箱子
    bool LandPlayerEvent::openPointInventory(std::shared_ptr<PlayerData> playerData, const Point3 &point, IInventory *inventory)
    {
        return playerEditBlockEvent(playerData, point);
    }

    // 移动物品
    bool LandPlayerEvent::playerHandleMoveItem(std::shared_ptr<PlayerData> playerData, IInventory *sourceInventory, uint32_t sourceSlotIndex, IInventory *targetInventory, int32_t targetSlotIndex, uint32_t count)
    {
        if (sourceInventory->blockEntity != nullptr)
        {
            Point3 &point = sourceInventory->blockEntity->coordinates;
            return playerEditBlockEvent(playerData, point);
        }
        return true;
    }
    // 点击移动物品
    bool LandPlayerEvent::playerHandleDragDrop(std::shared_ptr<PlayerData> playerData, IInventory *sourceInventory, uint32_t sourceSlotIndex, DragMode dragMode, IInventory *targetInventory, uint32_t targetSlotIndex, bool processingOnly)
    {
        if (sourceInventory->blockEntity != nullptr)
        {
            Point3 &point = sourceInventory->blockEntity->coordinates;
            return playerEditBlockEvent(playerData, point);
        }
        return true;
    }
    bool LandPlayerEvent::playerDrapDrop(ComponentPlayer *componentPlayer, const Vector3 &dropVelocity, IInventory *inventory, uint32_t slotIndex, uint32_t count)
    {
        if (inventory->blockEntity != nullptr)
        {
            Point3 &point = inventory->blockEntity->coordinates;
            return playerEditBlockEvent(componentPlayer->playerData, point);
        }
        return true;
    }
}


